home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / sdi / laser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-18  |  4.0 KB  |  167 lines

  1. /******************************  laser.c *******************************/
  2. #include <pixrect/pixrect_hs.h>
  3. #include <sunwindow/notify.h>
  4. #include "sdi.h"
  5.  
  6. /*
  7.  * Copyright 1987 by Mark Weiser.
  8.  * Permission to reproduce and use in any manner whatsoever on Suns is granted
  9.  * so long as this copyright and other identifying marks of authorship
  10.  * in the code and the game remain intact and visible.  Use of this code
  11.  * in other products is reserved to me--I'm working on Mac and IBM versions.
  12.  */
  13.  
  14. /*
  15.  * All laser-specific code is here.
  16.  */
  17.  
  18. /* Kill up to this many missiles with one laser blast */
  19. #define MAX_LASERS 6
  20.  
  21. /* A missile must be lasered for this many time steps to kill it */
  22. #define LASER_KILL_TIME 3
  23.  
  24. /* A laser kill is worth this many points in the launch window. */
  25. static short laser_value = 50;
  26.  
  27. int find_lasers();
  28.  
  29. static struct laser {
  30.     Pixwin *pw;
  31.     short x, y;
  32.     short count, maxlasers;
  33.     short oldx[MAX_LASERS];
  34.     short oldy[MAX_LASERS];
  35.     struct missile *ptr[MAX_LASERS];
  36.     struct laser *next;
  37.     };    
  38.  
  39. struct laser *l_head = NULL;
  40.  
  41. /*
  42.  * Initialize a linked list of lasers.  Free any already
  43.  * on there.
  44.  */
  45. init_laser()
  46. {
  47.     struct laser *tmp;
  48.     while (l_head != NULL) {
  49.         tmp = l_head;
  50.         l_head = l_head->next;
  51.         free(tmp);
  52.     }
  53. }        
  54.  
  55. /* communication into 'find_lasers' */
  56. static struct blast fake_bid;
  57. static struct laser *current_l;
  58. static int global_laser_count;
  59.  
  60. /*
  61.  * Start a laser blast at position x,y in pixwin pw.
  62.  */
  63. start_laser(x, y, pw, laser_count, laser_range)
  64. int x, y;
  65. Pixwin *pw;
  66. {
  67.     struct blast *bid = &fake_bid;
  68.     struct laser *l = (struct laser *)calloc(sizeof(struct laser), 1);
  69.     struct missile *mptr;
  70.     int i;
  71.     /* Create a fake bid to use the intersection code. */
  72.     bid->x = x;
  73.     bid->y = y;
  74.     bid->width = laser_range;
  75.     update_blast_rect(bid);
  76.     /* initialize the laser structure */
  77.     l->pw = pw;
  78.     l->count = 0;
  79.     l->maxlasers = 0;
  80.     l->x = x;
  81.     l->y = y;
  82.     l->next = l_head;
  83.     l_head = l;
  84.     current_l = l;
  85.     global_laser_count = laser_count;
  86.     doto_missiles(find_lasers);
  87.     mptr = l->ptr[0];
  88.     for (i = 0; i < l->maxlasers; i += 1) {
  89.         l->oldx[i] = l->ptr[i]->x;
  90.         l->oldy[i] = l->ptr[i]->y;
  91.     }
  92.     start_blast(x, y, 0, 0, pw, lasercircles);
  93. }
  94.  
  95. /*
  96.  * Helper routine passed into 'doto_missiles'.  Uses the global variables
  97.  * 'current_l' and 'fake_bid' to try to find MAX_LASERS missiles within the
  98.  * range of this laser.
  99.  */
  100. find_lasers(mid)
  101. struct missile *mid;
  102. {
  103.     register current_count = current_l->maxlasers;
  104.     if (current_count < global_laser_count &&
  105.             single_intersect(&fake_bid, mid) &&
  106.             mid->pw == current_l->pw) {
  107.         current_l->ptr[current_count] = mid;
  108.         mid->refs += 1;
  109.         current_l->maxlasers += 1;
  110.     }
  111.     return current_count >= global_laser_count;
  112. }
  113.  
  114. /*
  115.  * This routine is called once each game timestep to update the status
  116.  * of all lasers.
  117.  */
  118. doto_lasers()
  119. {
  120.     /* bump the count of each laser.
  121.        for each whose count is >= LASER_KILL_TIME, kill its old arcs, start
  122.        a small blast at each missiles current position, and free the laser.
  123.     */
  124.     struct laser *lptr, *old_lptr = NULL;
  125.     int i;
  126.     lptr = l_head;
  127.     while (lptr != NULL) {
  128.         lptr->count += 1;
  129.         for (i=0; i < lptr->maxlasers; i += 1) {
  130.             if (lptr->count > 1) {
  131.                 /* remove old laser path */
  132.                 pw_vector(lptr->pw, lptr->x, lptr->y,
  133.                     lptr->oldx[i], lptr->oldy[i],
  134.                     PIX_NOT(PIX_SRC), 1);
  135.             }
  136.             if (lptr->count > LASER_KILL_TIME) {
  137.                 /* this laser is all done */
  138.                 destroy_missile(lptr->ptr[i]);
  139.                 if (lptr->ptr[i]->y >= 0) {
  140.                     /* blast only if the missile is within range */
  141.                     start_blast(lptr->ptr[i]->x, lptr->ptr[i]->y,
  142.                         0, 0, lptr->pw, laserkillcircles);
  143.                 }
  144.                 if (lptr->pw == citypw)
  145.                     bump_score(laser_value/5);
  146.                 else bump_score(laser_value);
  147.                 if (old_lptr == NULL) {
  148.                     /* at the head */
  149.                     l_head = lptr->next;
  150.                 } else {
  151.                     old_lptr->next = lptr->next;
  152.                 }
  153.             } else {
  154.                 /* track the missile */
  155.                 lptr->oldx[i] = lptr->ptr[i]->x;
  156.                 lptr->oldy[i] = lptr->ptr[i]->y;
  157.                 pw_vector(lptr->pw, lptr->x, lptr->y,
  158.                     lptr->ptr[i]->x, lptr->ptr[i]->y, PIX_SRC, 1);
  159.  
  160.                 old_lptr = lptr;
  161.             }
  162.         } /* end of for */
  163.         lptr = lptr->next;
  164.     } /* end of while */
  165. }
  166.  
  167.